#include "Tetraedre.hpp"

#include <algorithm>

using namespace std;

/**
 * Constructeur initialisant les 4 instances de Plan à partir des 4
 * sommets du Tetraedre.
 *
 * @param base1 sommet 1.
 * @param base2 sommet 2.
 * @param base3 sommet 3.
 * @param hauteur sommet 4.
 */
Tetraedre::Tetraedre(const Coord& base1, const Coord& base2, const Coord& base3,
		     const Coord& hauteur)
{
  Vecteur Pbase1(base1,base2),Pbase2(base1,base3);
  Vecteur Pbase3(base2,base3);
  Vecteur arrete1(base1,hauteur),arrete2(base2,hauteur);

  // cout << "Pbase1 = " << Pbase1 << endl;
  // cout << "Pbase2 = " << Pbase2 << endl;
  // cout << "Pbase3 = " << Pbase3 << endl;

  // cout << "arrête1 = " << arrete1 << endl;
  // cout << "arrête2 = " << arrete2 << endl;

  Vecteur vNormal1(Pbase1^Pbase2); // normal de la base tetraedre
  if (vNormal1*arrete1>0)
    vNormal1*=-1;
  Vecteur vNormal2(Pbase1^arrete1);
  if (vNormal2*vNormal1>0)
    vNormal2*=-1;
  Vecteur vNormal3(Pbase2^arrete1);
  if (vNormal3*vNormal1>0)
    vNormal3*=-1;
  Vecteur vNormal4(Pbase3^arrete2);
  if (vNormal4*vNormal1>0)
    vNormal4*=-1;
  // 4 plans qui composent le tetraedre
  listplan.push_back(Plan::SharedPtr (new Plan(vNormal1,base1)));
  listplan.push_back(Plan::SharedPtr (new Plan(vNormal2,hauteur)));
  listplan.push_back(Plan::SharedPtr (new Plan(vNormal3,hauteur)));
  listplan.push_back(Plan::SharedPtr (new Plan(vNormal4,hauteur)));
  // on prend l'intersection des plans
  listFC.push_back(FormeComposee::SharedPtr (new FormeComposee(inter,listplan[0].get(),listplan[1].get())));
  listFC.push_back(FormeComposee::SharedPtr (new FormeComposee(inter,listplan[2].get(),listplan[3].get())));
  form[0]=listFC[0].get();
  form[1]=listFC[1].get();
  op=inter;

  Nom = "Tetraèdre";
  PseudoCentre = base1 + 2. / 3. * ( Pbase1 + .5 * Pbase3 )
    + .5  * ( vNormal1 * arrete1 ) / vNormal1.norme() * vNormal1;

  vector< double > distances;
  distances.push_back( Vecteur( PseudoCentre, base1 ).norme() );
  distances.push_back( Vecteur( PseudoCentre, base2 ).norme() );
  distances.push_back( Vecteur( PseudoCentre, base3 ).norme() );
  distances.push_back( Vecteur( PseudoCentre, hauteur ).norme() );

  PseudoRayon = sqrt( *max_element( distances.begin(), distances.end() ) );
}

/**
 * Le destructeur n'a rien de spécial à faire.
 */
Tetraedre::~Tetraedre()
{}
